﻿using Microsoft.Xna.Framework;
using FarseerPhysics.Dynamics;
using lumo.display.object2D;
using System;
using FarseerPhysics.Factories;
using Microsoft.Xna.Framework.Graphics;
using lumo;
using FarseerPhysics.Dynamics.Contacts;
using game.character.weapon;
using lumo.input;
using lumo.display.light;
using game.character.bullet;
using Microsoft.Xna.Framework.Audio;

namespace game.character
{

    /// <summary>
    /// The player.
    /// </summary>
    public class GamePlayer : GameCharacter, IShootable
    {

        protected const string _Texture = "Graphics/Misc/Submarino 96";
        protected Light _Light;

        protected Microsoft.Xna.Framework.Vector2 _BaseForce;
        SoundEffect HitEffect;
        public game.character.bullet.BulletManager BulletManager { get; protected set; }
        public game.character.weapon.Weapon Weapon { get; protected set; }

        /// <summary>
        /// Constructor for player.
        /// </summary>
        public GamePlayer(LumoComponent component, GameMap map)
            : base(component, map)
        {
            _BaseForce = new Microsoft.Xna.Framework.Vector2(Global.Random.Next(125, 250) / 10000.0f, Global.Random.Next(125, 250) / 10000.0f);
            _Light = map.LightManager.CreateLight(512, 4f);
            HitEffect =  component.Content.Load<SoundEffect>("Audio/SE/Hit");
            // Save the texture.
            this.Texture = component.Content.Load<Texture2D>(_Texture);
        }

        public override void Setup()
        {
            // Create Submarine Body.
            base.Setup();

            // Reset the battler.
            Battler = new game.character.battle.GameActor(10000, 10000);
            BulletManager = new BulletManager();
            Weapon = new PlayerWeapon(_LumoComponent);
        }

        /// <summary>
        /// Called when hit.
        /// </summary>
        public override void OnHit()
        {
            base.OnHit();
            HitEffect.Play();
        }

        protected override void CreateBody()
        {
            // Create Submarine Body.
            Body = BodyFactory.CreateCircle(_GameMap.World, (this.Texture.Width / 2) / Global.PhysicsScale, 0.125f);
            Body.BodyType = BodyType.Dynamic;
            Body.CollisionCategories = Global.PhysicsCategory.Actor;
            Body.CollidesWith = Global.PhysicsCategory.AllBut(Global.PhysicsCategory.Actor | Global.PhysicsCategory.ActorBullet);
            Body.LinearDamping = 1.0f;
            Body.AngularDamping = 1.0f;
            Body.Restitution = 0.25f;

            // Origin.
            this.ScreenOrigin = new Vector2((this.Texture.Width / 2), (this.Texture.Width / 2));
        }

        /// <summary>
        /// Update the character.
        /// </summary>
        /// <param name="component">Update using lumo</param>
        public override void Update(LumoComponent component)
        {
            base.Update(component);
            BulletManager.Update(component);
            if (Battler.HP == 0)
                component.Scene = new scene.SceneGameOver();

            _Light.Position = ScreenPosition + new Vector2(16 * Global.AditionalTiles, 16 * Global.AditionalTiles);

            //
            if (Global.Cursor.GetButton(Cursor.Button.Left).Triggered)
                Weapon.Shoot(BulletManager, this.Position, Global.Camera.Position + new Vector2(Global.Cursor.X, Global.Cursor.Y), this.Body.LinearVelocity);
            
            // Apply a force to sub
            const float Force = 0.5f;
            Body.ApplyForce(Global.Controller.MovementThumbstick.Vector * new Vector2(Force, -Force));
            
            // Apply a force to sub
            float Rot = Body.Rotation % (float)Math.PI;
            float AbsRot = Math.Abs(Rot);
            if (AbsRot > 0)
                Body.ApplyTorque(-0.1f * AbsRot * Rot);

            if (Body.LinearVelocity.X > 0)
                ScreenMirrorX = false;
            else if (Body.LinearVelocity.X < 0)
                ScreenMirrorX = true;
        }

    }

}